#ifndef __FIFO_H__
#define __FIFO_H__ 

#include "stdint.h"
#include <stdlib.h>
#include <string.h>

#define FIFO_SUCCESS 0
#define FIFO_FAIL 1

typedef struct {
    void* buffer;           // Pointer to data storage area (dynamically allocated)
    uint16_t elem_size;     // Size of single element in bytes
    uint32_t capacity;      // Maximum number of elements in buffer
    volatile uint32_t head; // Write position index
    volatile uint32_t tail; // Read position index
    volatile uint32_t count;// Current element count
} FIFO_Instance;

typedef enum {
	FIFO_TEST_UART = 0,

	MAX_FIFO_INSTANCES
}fifo_index;

uint8_t fifo_create(fifo_index fifo_idx, uint16_t elem_size, uint16_t capacity);
uint8_t fifo_push(fifo_index fifo_idx, const void* data);
void* fifo_pop_addr(fifo_index fifo_idx);
uint8_t fifo_pop(fifo_index fifo_idx, void* output);
uint8_t fifo_is_empty(fifo_index fifo_idx);
uint8_t fifo_is_full(fifo_index fifo_idx);
uint8_t fifo_free(fifo_index fifo_idx);

#endif
